#region Using Statments
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Storage;
using System.IO;
using System.Xml.Serialization;
using System.Diagnostics;
using DanielsGameLibrary;
using DanielsGameLibrary.SkinnedModel;
using DanielsGameLibrary.Input;
using DanielsGameLibrary.Tools;
using DanielsGameLibrary.MathTools;
using ParticalEngin;
#endregion

public delegate void drawSceneDelegate(GraphicsDevice divice, Camera cam, GameTime gameTime, bool enablecliping, Vector4 clipingplane);
        

    public class Game1 : Microsoft.Xna.Framework.Game
    {
        

        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch; 
        
        Camera gameCamera;

        SkyDome Sky;

        CMap Map;
        

        //Water mywater;
        Hero player1;

        Texture2D dot;

        public List<Bomb> bombs;

        //ParticleEmitter explasionprtsys;
        bool drowoutput;

        ParticleSystem explosionParticles;
        ParticleSystem explosionSmokeParticles;
        ParticleSystem projectileTrailParticles;

        public static List<Pointlight> lights;

        Bomb testbomb;


        Model model;
        AnimationPlayer animationPlayer;

        public Game1()
        {
            
            graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";
            drowoutput = true;

            graphics.PreferredBackBufferHeight = 1000;
            graphics.PreferredBackBufferWidth = 1200;
            graphics.PreferMultiSampling = true;

            // Construct our particle system components.
            explosionParticles = new ExplosionParticleSystem(this, Content);
            explosionSmokeParticles = new ExplosionSmokeParticleSystem(this, Content);
            projectileTrailParticles = new ProjectileTrailParticleSystem(this, Content);

            
            explosionSmokeParticles.DrawOrder = 200;
            projectileTrailParticles.DrawOrder = 300;
            explosionParticles.DrawOrder = 400;

            // Register the particle system components.
            Components.Add(explosionParticles);
            Components.Add(explosionSmokeParticles);
            Components.Add(projectileTrailParticles);
            
        }

       
        protected override void Initialize()
        {
            testbomb = new Bomb(new Vector3(0, 0, 0), 0, Content, Vector3.Zero, Vector3.Zero, explosionParticles, explosionSmokeParticles, projectileTrailParticles);
           


            gameCamera = new Camera(this, GameConstants.ViewAngle, GameConstants.NearClip, GameConstants.FarClip);
            Vector2 center = new Vector2();


            center.X = (float)GraphicsDevice.Viewport.Width / 2;
            center.Y = (float)GraphicsDevice.Viewport.Height / 2;
            player1 = new Hero(center, new Vector3(0,200,0 ));

            gameCamera.attachment = player1;
            gameCamera.lookatt = true;
            gameCamera.offset = 40;
            

            //Sky = new SkyDome(GraphicsDevice, new Vector2(), 1.2f);
            Map = new CMap();
            
            
            bombs = new List<Bomb>();

           // explasionprtsys = new ParticleEmitter(this, 500, player1);
            
            base.Initialize();
        }

        


        

        protected override void LoadContent()
        {
           
            spriteBatch = new SpriteBatch(GraphicsDevice);

           // explasionprtsys.LoadContent();
            

           
            GameConstants.DefaultEffect = Content.Load<Effect>(@"Shaders\effect");



            GameConstants.Toon = Content.Load<Texture2D>(@"Textures\Toon");
            
            //Sky.LoadContent(Content, @"Models\dome", GameConstants.DefaultEffect);

            Map.load("Maps/triboxtestmap", Content);


            model = Content.Load<Model>("Models/dude");
            // Look up our custom skinning information.
            SkinningData skinningData = model.Tag as SkinningData;

            if (skinningData == null)
                throw new InvalidOperationException
                    ("This model does not contain a SkinningData tag.");

            // Create an animation player, and start decoding an animation clip.
            animationPlayer = new AnimationPlayer(skinningData);

            AnimationClip clip = skinningData.AnimationClips["Take 001"];
            animationPlayer.StartClip(clip);
            

            OutPut.inInitializ(new Rectangle(10, 10, 200, 800), 11, Content.Load<SpriteFont>(@"Fonts\Font1"));
            dot = Content.Load<Texture2D>(@"Textures\dot");


        }

       
        protected override void UnloadContent()
        {
           
        }

        
        protected override void Update(GameTime gameTime)
        {
            
            
            
            //updete mause and keboard
            CKeyBoard.Update();
            CMouse.Update();

            if (CKeyBoard.Escape.Released)
                Exit();
            //center maus
            int centerX = Window.ClientBounds.Width / 2;
            int centerY = Window.ClientBounds.Height / 2;
                
            Mouse.SetPosition(centerX, centerY);


            gameCamera.offset += CMouse.ScrollWheelDelta*0.1f;

            
            try
            {
                OutPut.Out(1000 / gameTime.ElapsedGameTime.Milliseconds);
            }
            catch
            {
                OutPut.Out("Ziro!");
            }

            
            
            gameCamera.Update();

            player1.Update(gameTime, this , Content,
                            explosionParticles, explosionSmokeParticles, projectileTrailParticles);
            player1.collision(Map.getMovabals());

            if (CKeyBoard.F1.Pressed)
                drowoutput = !drowoutput;
            if (CKeyBoard.F2.Pressed)
                OutPut.Clear();


            if (CKeyBoard.F4.Released)
                for (int i = 0; i < 300; i++)
                {
                    explosionParticles.AddParticle(player1.Position, player1.Vellasity);
                    explosionSmokeParticles.AddParticle(player1.Position, player1.Vellasity);
                }
                

            foreach (Bomb bomb in bombs)
            {
                bomb.Update(gameTime);
                bomb.collision(Map.getMovabals());

            }

            animationPlayer.Update(gameTime.ElapsedGameTime, true, Matrix.Identity);
          //  explasionprtsys.Update(gameTime);

            base.Update(gameTime);
        }

        protected override void Draw(GameTime gameTime)
        {
            //drawSceneDelegate calback = new drawSceneDelegate( DrawScene );
            //mywater.DrawMaps(GraphicsDevice, gameCamera, gameTime, calback);
            explosionParticles.SetCamera(gameCamera.ViewMatrix, gameCamera.ProjectionMatrix);
            explosionSmokeParticles.SetCamera(gameCamera.ViewMatrix, gameCamera.ProjectionMatrix);
            projectileTrailParticles.SetCamera(gameCamera.ViewMatrix, gameCamera.ProjectionMatrix);

            GraphicsDevice.Clear(Color.Blue);

            DrawScene(GraphicsDevice, gameCamera , gameTime, false, Math3D.CreatePlane(0f, Vector3.Up, true));
            player1.dibugdraw(GraphicsDevice, gameCamera.ViewMatrix, gameCamera.ProjectionMatrix, GameConstants.DefaultEffect);
            
            

            spriteBatch.Begin();
            if (drowoutput)
               OutPut.Draw(spriteBatch, dot);
            spriteBatch.End();


            

            base.Draw(gameTime);
        }

        
        void DrawScene(GraphicsDevice divice, Camera cam, GameTime gameTime, bool enablecliping, Vector4 clipingplane)
        {
           //Sky.Draw(gameCamera, GraphicsDevice, (float)gameTime.TotalGameTime.TotalMilliseconds);
            Map.Draw(gameCamera, enablecliping, clipingplane, divice);
            //testbomb.Draw(gameCamera, false, clipingplane, divice);                              
            //DrowAnimation();
            foreach (Bomb bomb in bombs)
            {
                bomb.Draw(gameCamera, enablecliping, clipingplane, divice);
                bomb.dibugdraw(GraphicsDevice, gameCamera.ViewMatrix, gameCamera.ProjectionMatrix, GameConstants.DefaultEffect);
            }
           
        }

        void DrowAnimation()
        {

            GraphicsDevice.DepthStencilState = DepthStencilState.Default;
            Matrix[] bones = animationPlayer.GetSkinTransforms();

           
            // Render the skinned mesh.
            foreach (ModelMesh mesh in model.Meshes)
            {
                foreach (SkinnedEffect effect in mesh.Effects)
                {
                    effect.SetBoneTransforms(bones);

                    effect.View = gameCamera.ViewMatrix;
                    effect.Projection = gameCamera.ProjectionMatrix;

                    effect.EnableDefaultLighting();

                    effect.SpecularColor = new Vector3(0.25f);
                    effect.SpecularPower = 16;
                }

                mesh.Draw();
            }
        }

        
    }

